package com.zenithmind.mall.pojo.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.zenithmind.common.base.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 秒杀订单实体 - 遵循单一职责原则，专门管理秒杀订单信息
 * 
 * @author ZenithMind Team
 * @since 2025-07-03
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("mall_seckill_order")
public class SeckillOrder extends BaseEntity {

    /**
     * 秒杀订单号
     */
    private String seckillOrderNo;

    /**
     * 用户ID
     */
    private String userId;

    /**
     * 秒杀活动ID
     */
    private String activityId;

    /**
     * 秒杀商品ID
     */
    private String seckillProductId;

    /**
     * 商品ID
     */
    private String productId;

    /**
     * 购买数量
     */
    private Integer quantity;

    /**
     * 秒杀价格
     */
    private BigDecimal seckillPrice;

    /**
     * 原价
     */
    private BigDecimal originalPrice;

    /**
     * 总金额
     */
    private BigDecimal totalAmount;

    /**
     * 节省金额
     */
    private BigDecimal savedAmount;

    /**
     * 订单状态（0-待支付，1-已支付，2-已取消，3-已超时）
     */
    private Integer status;

    /**
     * 支付时间
     */
    private LocalDateTime paymentTime;

    /**
     * 取消时间
     */
    private LocalDateTime cancelTime;

    /**
     * 超时时间
     */
    private LocalDateTime timeoutTime;

    /**
     * 支付超时分钟数
     */
    private Integer paymentTimeoutMinutes;

    /**
     * 取消原因
     */
    private String cancelReason;

    /**
     * 关联的正式订单ID
     */
    private String orderId;

    // 业务方法

    /**
     * 检查是否待支付
     */
    public boolean isPendingPayment() {
        return Objects.equals(this.status, 0);
    }

    /**
     * 检查是否已支付
     */
    public boolean isPaid() {
        return Objects.equals(this.status, 1);
    }

    /**
     * 检查是否已取消
     */
    public boolean isCancelled() {
        return Objects.equals(this.status, 2);
    }

    /**
     * 检查是否已超时
     */
    public boolean isTimeout() {
        return Objects.equals(this.status, 3);
    }

    /**
     * 检查是否可以支付
     */
    public boolean canPay() {
        return isPendingPayment() && !isExpired();
    }

    /**
     * 检查是否可以取消
     */
    public boolean canCancel() {
        return isPendingPayment();
    }

    /**
     * 检查是否已过期
     */
    public boolean isExpired() {
        if (timeoutTime == null) {
            return false;
        }
        return LocalDateTime.now().isAfter(timeoutTime);
    }

    /**
     * 标记为已支付
     */
    public void markAsPaid() {
        if (canPay()) {
            this.status = 1;
            this.paymentTime = LocalDateTime.now();
        }
    }

    /**
     * 取消订单
     */
    public void cancel(String reason) {
        if (canCancel()) {
            this.status = 2;
            this.cancelTime = LocalDateTime.now();
            this.cancelReason = reason;
        }
    }

    /**
     * 标记为超时
     */
    public void markAsTimeout() {
        if (isPendingPayment()) {
            this.status = 3;
            this.cancelTime = LocalDateTime.now();
            this.cancelReason = "支付超时";
        }
    }

    /**
     * 设置支付超时时间
     */
    public void setPaymentTimeout(Integer minutes) {
        this.paymentTimeoutMinutes = minutes;
        if (minutes != null && minutes > 0) {
            this.timeoutTime = getCreateTime().plusMinutes(minutes);
        }
    }

    /**
     * 计算剩余支付时间（秒）
     */
    public Long getRemainingPaymentSeconds() {
        if (timeoutTime == null || !isPendingPayment()) {
            return null;
        }
        
        LocalDateTime now = LocalDateTime.now();
        if (now.isAfter(timeoutTime)) {
            return 0L;
        }
        
        return java.time.Duration.between(now, timeoutTime).getSeconds();
    }

    /**
     * 计算折扣率
     */
    public BigDecimal getDiscountRate() {
        if (originalPrice == null || originalPrice.compareTo(BigDecimal.ZERO) <= 0 ||
            seckillPrice == null || seckillPrice.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        
        return originalPrice.subtract(seckillPrice)
                          .divide(originalPrice, 2, java.math.RoundingMode.HALF_UP);
    }

    /**
     * 计算总节省金额
     */
    public BigDecimal getTotalSavedAmount() {
        if (savedAmount != null) {
            return savedAmount;
        }
        
        if (originalPrice != null && seckillPrice != null && quantity != null) {
            BigDecimal unitSaved = originalPrice.subtract(seckillPrice);
            return unitSaved.multiply(new BigDecimal(quantity));
        }
        
        return BigDecimal.ZERO;
    }

    /**
     * 获取状态名称
     */
    public String getStatusName() {
        if (status == null) return "未知";
        
        switch (status) {
            case 0: return "待支付";
            case 1: return "已支付";
            case 2: return "已取消";
            case 3: return "已超时";
            default: return "未知";
        }
    }

    /**
     * 生成秒杀订单号
     */
    public static String generateSeckillOrderNo() {
        return "SK" + System.currentTimeMillis() + 
               String.format("%04d", (int)(Math.random() * 10000));
    }

    /**
     * 验证秒杀订单数据完整性
     */
    public boolean isValid() {
        return seckillOrderNo != null && !seckillOrderNo.trim().isEmpty() &&
               userId != null && !userId.trim().isEmpty() &&
               activityId != null && !activityId.trim().isEmpty() &&
               seckillProductId != null && !seckillProductId.trim().isEmpty() &&
               productId != null && !productId.trim().isEmpty() &&
               quantity != null && quantity > 0 &&
               seckillPrice != null && seckillPrice.compareTo(BigDecimal.ZERO) > 0 &&
               totalAmount != null && totalAmount.compareTo(BigDecimal.ZERO) > 0 &&
               status != null && status >= 0 && status <= 3;
    }

    /**
     * 检查金额是否一致
     */
    public boolean isAmountConsistent() {
        if (seckillPrice == null || quantity == null) {
            return false;
        }
        
        BigDecimal calculated = seckillPrice.multiply(new BigDecimal(quantity));
        return totalAmount != null && calculated.compareTo(totalAmount) == 0;
    }
}
